/***********************************************************************************
 * 文件名： app.c
 * 版本： 1
 * 说明：
 * 		通信功能实现。目前通信功能仅用来防伪。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
***********************************************************************************/
#include "a-comm.h"
#include "polsys.h"

static u8 Comm_mRxStep = 0;
static u8 Comm_mRxLen;
static u8 Comm_mRxData[8];
volatile static bit Comm_mRxFilish = false;
volatile static bit Comm_mError = false;
bit _Comm_mRuning = false;
static u8 Comm_mRunTime;
static u8 Comm_mRunTime2;

// 内部函数声明

static void Encrypt();

// 对外接口函数

// 开始通信。进入通信模式
void Comm_Start()
{
    Comm_mRxStep = 0;
    Comm_mRunTime = 0;
    _Comm_mRuning = true;
    SUart_Enable();
}

// 间隔100ms执行一次，类似定时器中断
void Comm_Loop()
{
    if (_Comm_mRuning)
    {
        if(++Comm_mRunTime2>=3)
        {
            Comm_mRunTime2=0;
       
            Comm_mRunTime++;
            if (Comm_mRunTime == 3) // 900ms都没有收到一包数据，退出
            {
                _Comm_mRuning = false;
                SUart_Disable();
                BMLite_SetRefreshStatus(true);
            }
            if (Comm_mRxFilish) // 收到一包数据
            {
                int i;
                Encrypt();            // 对数据进行加密运算
                SUart_SendByte(0X55); // 返回加密后的数据
                while (SUart_GetTxFlag())
                {
                    Wdt_Clear();
                }
                SUart_SendByte(0XAA);
                while (SUart_GetTxFlag())
                {
                    Wdt_Clear();
                }
                for (i = 0; i < 8; i++)
                {
                    SUart_SendByte(Comm_mRxData[i]);
                    while (SUart_GetTxFlag())
                    {
                        Wdt_Clear();
                    }
                }
                _Comm_mRuning = false;
                SUart_Disable();
                BMLite_SetRefreshStatus(true);
                Comm_mRxFilish = false;
            }
            if (Comm_mError)
            {
                _Comm_mRuning = false;
                SUart_Disable();
                BMLite_SetRefreshStatus(true);
                Comm_mError = false;
            }
        }
    }
}

// 事件函数（类似中断，不需要再声明）

// SUART（软UART）事件，注意运行在中断中，禁止执行耗时操作。
void SUart_Event(suart_ev_t e)
{
    if (e == SUART_EV_RX_DONE) // 收到1个字节
    {

        if (Comm_mRxStep == 0)
        {
            if (SUart_GetRxByte() == 0X55)
            {
                Comm_mRxStep = 1;
            }
        }
        else if (Comm_mRxStep == 1)
        {
            if (SUart_GetRxByte() == 0XAA)
            {
                Comm_mRxLen = 0;
                Comm_mRxStep = 2;
            }
            else
            {
                Comm_mRxStep = 0;
            }
        }
        else if (Comm_mRxStep == 2)
        {
            Comm_mRxData[Comm_mRxLen] = SUart_GetRxByte();
            Comm_mRxLen++;
            if (Comm_mRxLen == 4)
            {
                Comm_mRxFilish = true;
                Comm_mRxStep = 0;
            }
        }
    }
    else if (e == SUART_EV_STOP_ERR) // 未收到正确的停止位
    {
        Comm_mError = true;
        Comm_mRxStep = 0;
    }
}

// 内部函数

// 静态加密参数
#define _COMM_CODE0 57
#define _COMM_CODE1 189

// 把4字节数据通过一系列运算得出8字节数据。
static void Encrypt()
{
    u8 i, left = 7, mid = 0, right = 1;
    Comm_mRxData[4] = Comm_mRxData[1] ^ _COMM_CODE0;
    Comm_mRxData[5] = Comm_mRxData[2] + _COMM_CODE1;
    Comm_mRxData[6] = Comm_mRxData[0] - Comm_mRxData[2];
    Comm_mRxData[7] = Comm_mRxData[1] ^ Comm_mRxData[3];

    for (i = 0; i < 100; i++)
    {
        *(Comm_mRxData + mid) = (*(Comm_mRxData + left) << 1) + (~*(Comm_mRxData + right));
        mid++;
        if (mid == 8)
            mid = 0;
        left++;
        if (left == 8)
            left = 0;
        right++;
        if (right == 8)
            right = 0;
        Wdt_Clear();
    }
}
